using System;

namespace Seaskyer.WebApp.Utility.BigUpload
{
	/// <summary>
	/// Enum of upload state.
	/// </summary>
	public enum UploadState : byte
	{
		/// <summary>
		/// 
		/// </summary>
		Error = 5,
		/// <summary>
		/// 
		/// </summary>
		Completed = 4,
		/// <summary>
		/// 
		/// </summary>
		Initializing = 0,
		/// <summary>
		/// 
		/// </summary>
		Moving = 3,
		/// <summary>
		/// 
		/// </summary>
		Uploaded = 2,
		/// <summary>
		/// 
		/// </summary>
		Uploading = 1
	}

	/// <summary>
	/// 
	/// </summary>
	public class UploadStatus : IDisposable
	{
		#region Fields

		private DateTime beginTime;
		private int fileCount;
		private long fileLength;
		private string fileName;
		private bool isActive;
		private int percent;
		private long readLength;
		private string uploadID;
		private UploadState state;
		#endregion

		#region Properties

		internal DateTime BeginTime
		{
			get { return this.beginTime; }
		}

		/// <summary>
		/// 
		/// </summary>
		public int FileCount
		{
			get { return this.fileCount; }
			set { this.fileCount = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		public long FileLength
		{
			get { return this.fileLength; }
			set { this.fileLength = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		public string FileName
		{
			get { return this.fileName; }
			set { this.fileName = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		public bool IsActive
		{
			get { return this.isActive; }
		}

		/// <summary>
		/// 
		/// </summary>
		public TimeSpan LeftTime
		{
			get
			{
				TimeSpan span = TimeSpan.MaxValue;
				if ((this.fileLength - this.readLength) > 0)
				{
					span = new TimeSpan(0, 0, ((int) Math.Round((this.fileLength - this.readLength)/this.Speed, 0)));
				}

				return span;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public int Percent
		{
			get
			{
				if (this.fileLength > 0)
				{
					this.percent = ((int) Math.Floor(((this.readLength*100)/this.fileLength)));
				}

				return this.percent;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public long ReceivedLength
		{
			get { return this.readLength; }
			set
			{
				this.readLength = value;
				if (this.readLength < this.fileLength)
				{
					this.state = UploadState.Uploading;
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public double Speed
		{
			get
			{
				TimeSpan span = DateTime.Now.Subtract(this.beginTime);
				double totalSeconds = span.TotalSeconds;
				double speed = 0;

				if ((totalSeconds == 0) && (this.readLength == this.fileLength))
				{
					totalSeconds = 1;
				}
				if (totalSeconds > 0)
				{
					speed = Math.Round(this.readLength/totalSeconds, 2);
				}

				return speed;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public UploadState State
		{
			get { return this.state; }
			set { this.state = value; }
		}

		#endregion

		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		internal UploadStatus()
		{
			this.fileLength = 0;
			this.readLength = 0;
			this.state = UploadState.Initializing;
			this.percent = 0;
			this.beginTime = DateTime.MinValue;
			this.isActive = true;
			this.uploadID = string.Empty;
			this.fileName = string.Empty;
			this.fileCount = 0;
			this.beginTime = DateTime.Now;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="UploadID"></param>
		public UploadStatus(string UploadID)
		{
			this.fileLength = 0;
			this.readLength = 0;
			this.state = UploadState.Initializing;
			this.percent = 0;
			this.beginTime = DateTime.MinValue;
			this.isActive = true;
			this.uploadID = string.Empty;
			this.fileName = string.Empty;
			this.fileCount = 0;
			this.uploadID = UploadID;

			UploadStatus uploadStatus = ((UploadStatus) Utils.GetContext().Application[("_UploadGUID_" + UploadID)]);

			if (uploadStatus != null)
			{
				this.fileLength = uploadStatus.fileLength;
				this.readLength = uploadStatus.ReceivedLength;
				this.percent = uploadStatus.Percent;
				this.state = uploadStatus.State;
				this.beginTime = uploadStatus.BeginTime;
				this.fileName = uploadStatus.FileName;
				this.fileCount = uploadStatus.FileCount;
			}

			this.isActive = (Utils.GetContext().Application[("_UploadGUID_" + UploadID)] != null);
		}

		#endregion

		/// <summary>
		/// Clear application variable.
		/// </summary>
		public void Dispose()
		{
			if (this.uploadID != string.Empty)
			{
				Utils.GetContext().Application.Remove(("_UploadGUID_" + this.uploadID));
			}
		}

		/// <summary>
		/// 
		/// </summary>
		~UploadStatus()
		{
			if (this.uploadID != string.Empty)
			{
				Utils.GetContext().Application.Remove(("_UploadGUID_" + this.uploadID));
			}
		}
	}

}